package com.comm.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;

/**
 * @class MyHttpClient.class 解析html文件
 * @method getHtmlSourceCode(String url);取到html源文件。以String 格式 返回.
 * @method getHtmlAsReader(String url) ;取到html源文件。以 BufferReader 文件流格式 返回.
 * @method getDescription(String page);通过正则表达式,获取description的时候 ; page可以是String
 *         or 文件流toString()。
 * @author pc221
 * 
 */

public final class MyHttpClient {

	public static Logger logger = Logger.getLogger(MyHttpClient.class);

	public static PostMethod getPostMethod(String url, String[] textname,
			String[] params, String charset) throws IOException, IOException {
		// 1.生成httpclient实例

		HttpClient httpClient = new HttpClient();

		// 2.post生成Post 方法

		PostMethod postMethod = new PostMethod(url);

		// 参数
		NameValuePair[] data = new NameValuePair[params.length];

		for (int x = 0; x < params.length; x++) {
			data[x] = new NameValuePair(textname[x], params[x]);
			logger.info("设置第" + (x + 1) + "参数{[key=" + textname[x] + "][value="
					+ params[x] + "]}");
			System.out.println("设置第" + (x + 1) + "参数{[key=" + textname[x]
					+ "][value=" + params[x] + "]}");

		}
		logger.info(data);

		// 3设置编码

		httpClient.getParams().setParameter(
				HttpMethodParams.HTTP_CONTENT_CHARSET, charset);

		// 4提交请求
		postMethod.setRequestBody(data);

		/* 3.执行 HTTP GET 请求 */

		int statusCode = httpClient.executeMethod(postMethod);
		// 判断访问的状态码
		if (statusCode != HttpStatus.SC_OK) {
			System.err.println("Method failed: " + postMethod.getStatusLine());

		}

		// 返回结果
		System.out.println(postMethod.getResponseBodyAsString());
		System.out.println(postMethod.getResponseBodyAsStream());
		// 301 or 302 继续提交
		return postMethod;

	}

	public static PostMethod getPostMethod(String url,
			Map<String, String[]> map, String charset) throws IOException,
			IOException {

		// 1.生成httpclient实例

		HttpClient httpClient = new HttpClient();

		// 2.post生成Post 方法

		PostMethod postMethod = new PostMethod(url);

		// 参数
		NameValuePair[] data = new NameValuePair[map.size()];
		int index = 0;
		Set<String> keyMap = map.keySet();
		for (String mapKey : keyMap) {
			if (StringUtil.isEmpty(mapKey))
				continue;
			String[] values = (String[]) map.get(mapKey);
			if (values == null || values.length == 0)
				continue;
			data[index] = new NameValuePair(mapKey, values[0]);
			logger.info("设置第" + (index + 1) + "参数{[key=" + mapKey + "][value="
					+ values[0] + "]}");
			System.out.println("设置第" + (index + 1) + "参数{[key=" + mapKey
					+ "][value=" + values[0] + "]}");
			index++;

		}
		logger.info(data);

		// 3设置编码

		httpClient.getParams().setParameter(
				HttpMethodParams.HTTP_CONTENT_CHARSET, charset);

		// 4提交请求
		postMethod.setRequestBody(data);

		/* 3.执行 HTTP GET 请求 */

		int statusCode = httpClient.executeMethod(postMethod);
		// 判断访问的状态码
		if (statusCode != HttpStatus.SC_OK) {
			System.err.println("Method failed: " + postMethod.getStatusLine());

		}

		// 返回结果
		System.out.println(postMethod.getResponseBodyAsString());
		System.out.println(postMethod.getResponseBodyAsStream());

		// 301 or 302 继续提交
		return postMethod;

	}

	/**
	 * httpClient 封装,调用此方法后，需要写程序释放 Method ; Method.releaseConnection()
	 * GetMethod(String url);
	 * 
	 * @param url
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */

	public static GetMethod getPostMethod(String url) throws IOException,
			IOException {
		/* 1.生成 HttpClinet 对象并设置参数 */
		HttpClient httpClient = new HttpClient();
		// 设置 Http 连接超时 5s
		httpClient.getHttpConnectionManager().getParams()
				.setConnectionTimeout(50000);

		httpClient.getParams().setParameter(
				HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");

		/* 2.生成 GetMethod 对象并设置参数 */
		GetMethod getMethod = new GetMethod(url);

		// 设置 get 请求超时 20s
		getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 20000);
		// 设置请求重试处理
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());

		/* 3.执行 HTTP GET 请求 */

		int statusCode = httpClient.executeMethod(getMethod);
		// 判断访问的状态码
		if (statusCode != HttpStatus.SC_OK) {
			System.err.println("Method failed: " + getMethod.getStatusLine());

		}

		/* 4.处理 HTTP 响应内容 */
		// byte[] responseBody = getMethod.getResponseBody();// 读取为字节数组
		// InputStream in = getMethod.getResponseBodyAsStream();
		return getMethod;

	}

	/**
	 * 取到传入URL页面的HTML源文件。
	 * 
	 * @param 参数
	 *            url
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */

	public static String getHtmlSourceCode(String url) throws HttpException,
			IOException {
		GetMethod getMethod = null;
		try {
			getMethod = getPostMethod(url);
			byte[] responseBody = getMethod.getResponseBody();
			String htmlsrc = new String(responseBody,"utf-8");
			System.out.println(htmlsrc);
			return htmlsrc;
		} finally {
			// 释放连接
			if (getMethod != null)
				getMethod.releaseConnection();

		}

	}

	public static byte[] getByteArray(String url) throws HttpException,
			IOException {
		GetMethod getMethod = null;
		try {
			getMethod = getPostMethod(url);
			return getMethod.getResponseBody();

		} finally {
			// 释放连接
			if (getMethod != null)
				getMethod.releaseConnection();

		}

	}

	public static InputStream getResponseBodyAsStream(String url)
			throws HttpException, IOException {
		GetMethod getMethod = null;
		try {
			getMethod = getPostMethod(url);
			return getMethod.getResponseBodyAsStream();

		} finally {
			// 释放连接
			if (getMethod != null)
				getMethod.releaseConnection();

		}

	}
    /**
     * 
     * 
     * @param url
     * @return
     * @throws HttpException
     * @throws IOException
     */
	public static String getResponseBodyAsString(String url)
			throws HttpException, IOException {
		GetMethod getMethod = null;
		try {
			getMethod = getPostMethod(url);
			return getMethod.getResponseBodyAsString();

		} finally {
			// 释放连接
			if (getMethod != null)
				getMethod.releaseConnection();

		}

	}

	/**
	 * 取到传入filepath的文件流。
	 * 
	 * @param 参数
	 * 
	 * @return
	 * @throws IOException
	 */

	public static BufferedReader getHtmlAsReader(String filepath)
			throws IOException {

		BufferedReader reader = new BufferedReader(new FileReader(new File(
				filepath)));

		return reader;
	}

	/**
	 * 取到传入URL页面的HTML文件流。
	 * 
	 * @param 参数
	 *            url
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */

	public static BufferedReader getHtmlAsReader(String url, String filepath)
			throws HttpException, IOException {
		GetMethod getMethod = getPostMethod(url);
		try {
			InputStream in = getMethod.getResponseBodyAsStream();
			BufferedReader reader = new BufferedReader(new FileReader(new File(
					filepath)));
			while (reader.ready()) {
				System.out.println("MyHttpClient.class.getHtmlAsReader(url):"
						+ reader.readLine());
			}
			return reader;
		} finally {
			// 释放连接
			getMethod.releaseConnection();

		}
	}

	public static BufferedReader getHtmlAsReader_tmp(String url)
			throws HttpException, IOException {
		GetMethod getMethod = getPostMethod(url);
		try {
			InputStream in = getMethod.getResponseBodyAsStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					in, "UTF-8"));
			while (reader.ready()) {
				System.out.println("MyHttpClient.class.getHtmlAsReader(url):"
						+ reader.readLine());

			}
			return reader;
		} finally {
			// 释放连接
			getMethod.releaseConnection();

		}
	}

	public static void DownLoadPages(String urlStr, String outPath) {
		int chByte = 0;
		URL url = null;
		HttpURLConnection httpConn = null;
		InputStream in = null;
		FileOutputStream out = null;

		try {
			url = new URL(urlStr);
			httpConn = (HttpURLConnection) url.openConnection();
			HttpURLConnection.setFollowRedirects(true);
			httpConn.setRequestMethod("GET");
			httpConn.setRequestProperty("User-Agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows xp)");
			System.out.print(httpConn.getResponseMessage());

			logger.info(httpConn.getResponseMessage());
			logger.info(httpConn.getContent());
			System.out.print(httpConn.getResponseCode());
			in = httpConn.getInputStream();
			out = new FileOutputStream(new File(outPath));

			chByte = in.read();
			while (chByte != -1) {
				out.write(chByte);
				chByte = in.read();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
				in.close();
				httpConn.disconnect();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	public static void DownLoadPagesPay(String urlStr, String outPath) {
		int chByte = 0;
		URL url = null;
		HttpURLConnection httpConn = null;
		InputStream in = null;
		FileOutputStream out = null;

		try {
			url = new URL(urlStr);
			httpConn = (HttpURLConnection) url.openConnection();
			HttpURLConnection.setFollowRedirects(true);
			httpConn.setRequestMethod("GET");
			httpConn.setRequestProperty("User-Agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows xp)");
			// System.out.print(httpConn.getResponseMessage()
			// + httpConn.getResponseCode());
			in = httpConn.getInputStream();
			out = new FileOutputStream(new File(outPath));

			chByte = in.read();
			while (chByte != -1) {
				out.write(chByte);
				chByte = in.read();
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
				in.close();
				httpConn.disconnect();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}

	}

	/**
	 * 通过正则表达式,获取description的时候 ;
	 * 
	 * @param page
	 * @return
	 */
	// <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
	public static String getDescription(String page) {
		String description = null;
		// 过滤<meta
		Pattern pattern = Pattern.compile(
				"(<meta)(.*)name *= *[\"\'] *description *[\"\'](.*)(/>)",
				Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(page);

		// boolean found = false;//flag indicating whether the page has a
		// description.
		String resultStr = null;
		while (matcher.find()) {
			resultStr = matcher.group();
			// 取到 内容
			Pattern patternDesc = Pattern.compile(
					"(charset *= *[\"\'])(.*)([\"\'])",
					Pattern.CASE_INSENSITIVE);
			Matcher matcherDesc = patternDesc.matcher(resultStr);
			while (matcherDesc.find()) {
				description = matcherDesc.group(2);
				System.out.println(description);
			}
			// found = true;
		}

		// If no description found, then set title as its description
		/*
		 * if(!found){ description = title; }
		 */

		return description;
	}

	private static String getTag(String pattern, String str) {
		System.out.println(str);
		Pattern sp = Pattern.compile(pattern);
		Matcher matcher = sp.matcher(str);
		while (matcher.find()) {
			for (int i = 0; i < matcher.groupCount(); i++) {
				System.out.println("  html 正则表达式解析 " + matcher.group(i));

			}
		}
		return "";
	}

	private static String convert(String str) {
		StringBuffer sb = new StringBuffer(1024);
		sb.setLength(0);
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (c > 255) {
				sb.append("\\u");
				int j = (c >>> 8);
				String tmp = Integer.toHexString(j);
				if (tmp.length() == 1) {
					sb.append("0");
				}
				sb.append(tmp);
				j = (c & 0xFF);
				tmp = Integer.toHexString(j);
				if (tmp.length() == 1) {
					sb.append("0");
				}
				sb.append(tmp);
			} else {
				sb.append(c);
			}
		}
		return (new String(sb));
	}

	public static void main(String[] args) { }

}
